﻿using System.Collections.Generic;

namespace RegExpRegExpGenerator
{
    public class CodeRegExpGenerator
    {
        /// <summary>
        ///     Generates Lexer code
        /// </summary>
        /// <param name="Namespace"></param>
        /// <param name="rules"></param>
        /// <returns></returns>
        public static string Generate(string Namespace, List<LexRule> rules)
        {
            string CODE = "";

            // Add required imports
            CODE += "using System.Collections.Generic;\nusing System.Text.RegularExpressions;\n\n";

            // Add user-specified namespace
            CODE += "\nnamespace {Namespace}";
            CODE += "\n{";
            CODE += "\n   public class Lexer";
            CODE += "\n   {";
            CODE += "\n       public Lexer(string Code) { this.Code = Code; }";
            CODE +=
                "\n       public string Code { get; set; }\n\n        public Dictionary<string, string> Tokenize()\n      {";
            CODE += "\n           Dictionary<string, string> Output = new Dictionary<string, string>();";
            CODE += "\n           int Pos = 0;\n";
            CODE += "\n           while (Pos < Code.Length)";
            CODE += "\n           {";

            // Push all user-specified rules

            foreach (LexRule lr in rules)
            {
                CODE += "\n  if (new Regex({lr.Pattern}).Match(Code, Pos).Success)\n              {";
                CODE += "\n                 var Match = new Regex({lr.Pattern}).Match(Code, Pos);";

                if (!lr.Ignored) // If the rule is ignored
                {
                    CODE += "\n                 Output.Add(\"{lr.Name}\", Match.ToString());";
                }

                CODE += "\n                 Pos += Match.ToString().Length;";
                CODE += "\n              }\n\n";
            }

            CODE += "              Code = Code.Substring(Pos).Trim();Pos = 0;";
            CODE += "\n           }";
            CODE += "\n\n           return Output;";
            CODE += "\n       }";
            CODE += "\n   }";
            CODE += "\n}";

            return CODE;
        }
    }
}